namespace Maple.Branch.Identity
{
    using AotuMappers;
    using Entities;
    using Etos;
    using Extensions;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.DependencyInjection.Extensions;
    using Microsoft.Extensions.Options;
    using Options;
    using Users;
    using Users.Domain;
    using Volo.Abp.AutoMapper;
    using Volo.Abp.Domain;
    using Volo.Abp.EventBus.Distributed;
    using Volo.Abp.Modularity;

    [DependsOn(typeof(AbpDddDomainModule),
        typeof(AbpAutoMapperModule),
        typeof(UsersDomainModule),
        typeof(IdentityCommonModule))]
    public class IdentityDomainModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAutoMapperObjectMapper<IdentityDomainModule>();

            Configure<AbpAutoMapperOptions>(options =>
            {
                options.AddProfile<IdentityMapperProfile>(validate: true);
            });

            Configure<AbpDistributedEventBusOptions>(options =>
            {
                options.EtoMappings.Add<IdentityUser, UserEto>(typeof(IdentityDomainModule));
                options.EtoMappings.Add<IdentityClaimType, IdentityClaimTypeEto>(typeof(IdentityDomainModule));
                options.EtoMappings.Add<IdentityRole, IdentityRoleEto>(typeof(IdentityDomainModule));
            });

            var identityBuilder = context.Services.AddIdentity(options =>
            {
                options.User.RequireUniqueEmail = true;
            });

            context.Services.AddObjectAccessor(identityBuilder);

            context.Services.ExecutePreConfiguredActions(identityBuilder);

            AddIdentityOptionsFactory(context.Services);
        }

        private static void AddIdentityOptionsFactory(IServiceCollection services)
        {
            services.Replace(ServiceDescriptor.Transient<IOptionsFactory<IdentityOptions>, IdentityOptionsFactory>());

            services.Replace(ServiceDescriptor.Scoped<IOptions<IdentityOptions>, OptionsManager<IdentityOptions>>());
        }
    }
}
